/* -------------------------------------------------------------------------
 *
 * objectaccess.c
 *		用于各种事件的object_access_hook函数
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * -------------------------------------------------------------------------
 */
#include "postgres.h"

#include "catalog/objectaccess.h"
#include "catalog/pg_class.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"

/*
 * 钩子对象访问。这是为安全
 * 和日志插件提供的基础设施。
 */
object_access_hook_type object_access_hook = NULL;
object_access_hook_type_str object_access_hook_str = NULL;


/*
 * RunObjectPostCreateHook
 *
 * OAT_POST_CREATE对象ID基础事件钩子入口
 */
void RunObjectPostCreateHook(Oid fc_classId, Oid fc_objectId, int fc_subId,
						bool fc_is_internal)
{
	ObjectAccessPostCreate fc_pc_arg;

	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook != NULL);

	memset(&fc_pc_arg, 0, sizeof(ObjectAccessPostCreate));
	fc_pc_arg.is_internal = fc_is_internal;

	(*object_access_hook) (OAT_POST_CREATE,
						   fc_classId, fc_objectId, fc_subId,
						   (void *) &fc_pc_arg);
}

/*
 * RunObjectDropHook
 *
 * OAT_DROP对象ID基础事件钩子入口
 */
void RunObjectDropHook(Oid fc_classId, Oid fc_objectId, int fc_subId,
				  int fc_dropflags)
{
	ObjectAccessDrop fc_drop_arg;

	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook != NULL);

	memset(&fc_drop_arg, 0, sizeof(ObjectAccessDrop));
	fc_drop_arg.dropflags = fc_dropflags;

	(*object_access_hook) (OAT_DROP,
						   fc_classId, fc_objectId, fc_subId,
						   (void *) &fc_drop_arg);
}

/*
 * RunObjectTruncateHook
 *
 * OAT_TRUNCATE对象ID基础事件钩子入口
 */
void RunObjectTruncateHook(Oid fc_objectId)
{
	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook != NULL);

	(*object_access_hook) (OAT_TRUNCATE,
						   RelationRelationId, fc_objectId, 0,
						   NULL);
}

/*
 * RunObjectPostAlterHook
 *
 * OAT_POST_ALTER对象ID基础事件钩子入口
 */
void RunObjectPostAlterHook(Oid fc_classId, Oid fc_objectId, int fc_subId,
					   Oid fc_auxiliaryId, bool fc_is_internal)
{
	ObjectAccessPostAlter fc_pa_arg;

	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook != NULL);

	memset(&fc_pa_arg, 0, sizeof(ObjectAccessPostAlter));
	fc_pa_arg.auxiliary_id = fc_auxiliaryId;
	fc_pa_arg.is_internal = fc_is_internal;

	(*object_access_hook) (OAT_POST_ALTER,
						   fc_classId, fc_objectId, fc_subId,
						   (void *) &fc_pa_arg);
}

/*
 * RunNamespaceSearchHook
 *
 * OAT_NAMESPACE_SEARCH对象ID基础事件钩子入口
 */
bool RunNamespaceSearchHook(Oid fc_objectId, bool fc_ereport_on_violation)
{
	ObjectAccessNamespaceSearch fc_ns_arg;

	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook != NULL);

	memset(&fc_ns_arg, 0, sizeof(ObjectAccessNamespaceSearch));
	fc_ns_arg.ereport_on_violation = fc_ereport_on_violation;
	fc_ns_arg.result = true;

	(*object_access_hook) (OAT_NAMESPACE_SEARCH,
						   NamespaceRelationId, fc_objectId, 0,
						   (void *) &fc_ns_arg);

	return fc_ns_arg.result;
}

/*
 * RunFunctionExecuteHook
 *
 * OAT_FUNCTION_EXECUTE对象ID基础事件钩子入口
 */
void RunFunctionExecuteHook(Oid fc_objectId)
{
	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook != NULL);

	(*object_access_hook) (OAT_FUNCTION_EXECUTE,
						   ProcedureRelationId, fc_objectId, 0,
						   NULL);
}

/* 字符串版本 */


/*
 * RunObjectPostCreateHookStr
 *
 * OAT_POST_CREATE对象名称基础事件钩子入口
 */
void RunObjectPostCreateHookStr(Oid fc_classId, const char *fc_objectName, int fc_subId,
						   bool fc_is_internal)
{
	ObjectAccessPostCreate fc_pc_arg;

	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook_str != NULL);

	memset(&fc_pc_arg, 0, sizeof(ObjectAccessPostCreate));
	fc_pc_arg.is_internal = fc_is_internal;

	(*object_access_hook_str) (OAT_POST_CREATE,
							   fc_classId, fc_objectName, fc_subId,
							   (void *) &fc_pc_arg);
}

/*
 * RunObjectDropHookStr
 *
 * OAT_DROP对象名称基础事件钩子入口
 */
void RunObjectDropHookStr(Oid fc_classId, const char *fc_objectName, int fc_subId,
					 int fc_dropflags)
{
	ObjectAccessDrop fc_drop_arg;

	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook_str != NULL);

	memset(&fc_drop_arg, 0, sizeof(ObjectAccessDrop));
	fc_drop_arg.dropflags = fc_dropflags;

	(*object_access_hook_str) (OAT_DROP,
							   fc_classId, fc_objectName, fc_subId,
							   (void *) &fc_drop_arg);
}

/*
 * RunObjectTruncateHookStr
 *
 * OAT_TRUNCATE对象名称基础事件钩子入口
 */
void RunObjectTruncateHookStr(const char *fc_objectName)
{
	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook_str != NULL);

	(*object_access_hook_str) (OAT_TRUNCATE,
							   RelationRelationId, fc_objectName, 0,
							   NULL);
}

/*
 * RunObjectPostAlterHookStr
 *
 * OAT_POST_ALTER对象名称基础事件钩子入口
 */
void RunObjectPostAlterHookStr(Oid fc_classId, const char *fc_objectName, int fc_subId,
						  Oid fc_auxiliaryId, bool fc_is_internal)
{
	ObjectAccessPostAlter fc_pa_arg;

	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook_str != NULL);

	memset(&fc_pa_arg, 0, sizeof(ObjectAccessPostAlter));
	fc_pa_arg.auxiliary_id = fc_auxiliaryId;
	fc_pa_arg.is_internal = fc_is_internal;

	(*object_access_hook_str) (OAT_POST_ALTER,
							   fc_classId, fc_objectName, fc_subId,
							   (void *) &fc_pa_arg);
}

/*
 * RunNamespaceSearchHookStr
 *
 * OAT_NAMESPACE_SEARCH对象名称基础事件钩子入口
 */
bool RunNamespaceSearchHookStr(const char *fc_objectName, bool fc_ereport_on_violation)
{
	ObjectAccessNamespaceSearch fc_ns_arg;

	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook_str != NULL);

	memset(&fc_ns_arg, 0, sizeof(ObjectAccessNamespaceSearch));
	fc_ns_arg.ereport_on_violation = fc_ereport_on_violation;
	fc_ns_arg.result = true;

	(*object_access_hook_str) (OAT_NAMESPACE_SEARCH,
							   NamespaceRelationId, fc_objectName, 0,
							   (void *) &fc_ns_arg);

	return fc_ns_arg.result;
}

/*
 * RunFunctionExecuteHookStr
 *
 * OAT_FUNCTION_EXECUTE对象名称基础事件钩子入口
 */
void RunFunctionExecuteHookStr(const char *fc_objectName)
{
	/* 调用者应检查，但以防万一... */
	Assert(object_access_hook_str != NULL);

	(*object_access_hook_str) (OAT_FUNCTION_EXECUTE,
							   ProcedureRelationId, fc_objectName, 0,
							   NULL);
}
